#lang racket/base
(require
 (for-syntax
  racket/base
  spire/core/expander)
 rackunit
 racket/base
 racket/match
 spire/core/literals
 spire/core/ast
 "util/check-expansion.rkt")

;; ===========
;; expand-to-core/shallow

(check-identity-expansion
 (#%sp:def a b)
 expand-to-core/shallow)

(check-identity-expansion
 (#%sp:let a b c d)
 expand-to-core/shallow)

(check-expansion
 4
 (#%sp:datum 4)
 expand-to-core/shallow)

(define-syntax (m stx) #'4)
(check-expansion
 (m foo)
 (#%sp:datum 4)
 expand-to-core/shallow)

(check-expansion
 (a b)
 (#%sp:app a b)
 expand-to-core/shallow)

(check-expansion
 ((m) c)
 (#%sp:app (m) c)
 expand-to-core/shallow)

(check-expansion
 {1 + 2}
 (#%sp:app + 1 2)
 expand-to-core/shallow)

(check-expansion
 {1 m 2}
 (#%sp:datum 4)
 expand-to-core/shallow)

;; ===========
;; expand-def/shallow

(check-expansion
 (#%sp:def x y)
 (#%sp:def x y)
 expand-def/shallow)

(define-syntax (n stx) #'(#%sp:def x y))
(check-expansion
 (n)
 (#%sp:def x y)
 expand-def/shallow)

(check-expansion
 (m)
 (#%sp:def ,_ (#%sp:datum 4))
 expand-def/shallow)

;; ===========
;; expand-expression

; #%sp:datum, #%sp

(check-expansion
 4
 (#%sp:datum 4)
 expand-expression)

(check-expansion-exn
 (#%sp:datum #px"bad")
 #px"invalid data literal"
 expand-expression)

; #%sp:app

(check-identity-expansion
 (#%sp:app f x y)
 expand-expression)

(check-identity-expansion
 (#%sp:app f x #:e y)
 expand-expression)

(check-expansion
 (#%sp:app f #:e y x)
 (#%sp:app f x #:e y)
 expand-expression)

(check-expansion-exn
 (#%sp:app f #:e y #:e x)
 #px"duplicate keyword"
 expand-expression)

; #%sp:λ

(check-identity-expansion
 (#%sp:λ (x y) (#%sp:datum #t))
 expand-expression)

(check-identity-expansion
 (#%sp:λ (m) m) ; shadows macro defn. of m
 expand-expression)

(check-identity-expansion
 (#%sp:λ (x #:e y) x)
 expand-expression)

(check-expansion
 (#%sp:λ (#:e y x) x)
 (#%sp:λ (x #:e y) x)
 expand-expression)

(check-expansion
 (#%sp:λ (x) (x (m)))
 (#%sp:λ (x) (#%sp:app x (#%sp:datum 4)))
 expand-expression)

; #%sp:let

(check-expansion
 (#%sp:let (t (m)) (t))
 (#%sp:let (t (#%sp:datum 4)) (#%sp:app t))
 expand-expression)

(check-identity-expansion
 (#%sp:let (m (#%sp:datum 8)) ; shadows macro defn. of m
           (x m)
           (#%sp:primop "PLUS"))
 expand-expression)
